package org.cybzacg.convert.context.impl;

import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.enums.ConversionStrategyEnum;
import org.cybzacg.convert.enums.ConversionType;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认转换上下文实现
 */
@Slf4j
public class DefaultConversionContext implements ConversionContext {
    private ConversionStrategyEnum strategy;
    private Class<?> sourceType;
    private Class<?> targetType;
    private ConversionType conversionType;
    private Object defaultValue;
    private final Map<String, Object> properties = new ConcurrentHashMap<>();
    private boolean cacheEnabled = true;
    private boolean validationEnabled = true;
    private long timeout = 5000; // 5秒默认超时
    private int depth = 0;

    public DefaultConversionContext() {
        this.strategy = ConversionStrategyEnum.SAFE;
        log.debug("创建默认转换上下文，策略: {}", strategy);
    }

    public DefaultConversionContext(ConversionStrategyEnum strategy) {
        this();
        this.strategy = strategy;
        log.debug("创建转换上下文，策略: {}", strategy);
    }

    @Override
    public ConversionStrategyEnum getStrategy() {
        return strategy;
    }

    @Override
    public void setStrategy(ConversionStrategyEnum strategy) {
        log.debug("设置转换策略: {} -> {}", this.strategy, strategy);
        this.strategy = strategy;
    }

    @Override
    public Class<?> getSourceType() {
        return sourceType;
    }

    @Override
    public void setSourceType(Class<?> sourceType) {
        log.debug("设置源类型: {} -> {}", this.sourceType, sourceType);
        this.sourceType = sourceType;
    }

    @Override
    public Class<?> getTargetType() {
        return targetType;
    }

    @Override
    public void setTargetType(Class<?> targetType) {
        log.debug("设置目标类型: {} -> {}", this.targetType, targetType);
        this.targetType = targetType;
    }

    @Override
    public ConversionType getConversionType() {
        return conversionType;
    }

    @Override
    public void setConversionType(ConversionType conversionType) {
        this.conversionType = conversionType;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getDefaultValue() {
        return (T) defaultValue;
    }

    @Override
    public <T> void setDefaultValue(T defaultValue) {
        log.debug("设置默认值: {} -> {}", this.defaultValue, defaultValue);
        this.defaultValue = defaultValue;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getProperty(String key) {
        return (T) properties.get(key);
    }

    @Override
    public <T> void setProperty(String key, T value) {
        log.debug("设置属性: {} = {}", key, value);
        properties.put(key, value);
    }

    @Override
    public Map<String, Object> getProperties() {
        return new ConcurrentHashMap<>(properties);
    }

    @Override
    public boolean isCacheEnabled() {
        return cacheEnabled;
    }

    @Override
    public void setCacheEnabled(boolean cacheEnabled) {
        log.debug("设置缓存启用: {} -> {}", this.cacheEnabled, cacheEnabled);
        this.cacheEnabled = cacheEnabled;
    }

    @Override
    public boolean isValidationEnabled() {
        return validationEnabled;
    }

    @Override
    public void setValidationEnabled(boolean validationEnabled) {
        log.debug("设置验证启用: {} -> {}", this.validationEnabled, validationEnabled);
        this.validationEnabled = validationEnabled;
    }

    @Override
    public long getTimeout() {
        return timeout;
    }

    @Override
    public void setTimeout(long timeout) {
        log.debug("设置超时时间: {} -> {}", this.timeout, timeout);
        this.timeout = timeout;
    }

    @Override
    public int getDepth() {
        return depth;
    }

    @Override
    public void setDepth(int depth) {
        log.debug("设置转换深度: {} -> {}", this.depth, depth);
        this.depth = depth;
    }

    @Override
    public void incrementDepth() {
        depth++;
        log.debug("增加转换深度: {}", depth);
    }

    @Override
    public boolean isDepthExceeded(int maxDepth) {
        boolean exceeded = depth > maxDepth;
        if (exceeded) {
            log.warn("转换深度超过限制: 当前深度={}, 最大深度={}", depth, maxDepth);
        }
        return exceeded;
    }

    @Override
    public ConversionContext createChildContext(Class<?> sourceType, Class<?> targetType) {
        log.debug("创建子上下文: {} -> {}", sourceType, targetType);
        DefaultConversionContext child = new DefaultConversionContext(this.strategy);
        child.setSourceType(sourceType);
        child.setTargetType(targetType);
        child.setConversionType(ConversionType.fromTypeName(targetType.getSimpleName()));
        child.setCacheEnabled(this.cacheEnabled);
        child.setValidationEnabled(this.validationEnabled);
        child.setTimeout(this.timeout);
        child.setDepth(this.depth);
        child.properties.putAll(this.properties);
        return child;
    }

    @Override
    public ConversionContext copy() {
        log.debug("复制上下文");
        DefaultConversionContext copy = new DefaultConversionContext(this.strategy);
        copy.setSourceType(this.sourceType);
        copy.setTargetType(this.targetType);
        copy.setConversionType(this.conversionType);
        copy.setDefaultValue(this.defaultValue);
        copy.setCacheEnabled(this.cacheEnabled);
        copy.setValidationEnabled(this.validationEnabled);
        copy.setTimeout(this.timeout);
        copy.setDepth(this.depth);
        copy.properties.putAll(this.properties);
        return copy;
    }

    @Override
    public void clear() {
        log.debug("清理上下文");
        properties.clear();
        depth = 0;
        defaultValue = null;
    }
}
